<?php

namespace mpend\modules\passport\models;

use Yii;
use yii\db\Exception;
use common\base\Model;
use common\models\user\UserMeta;
use common\helpers\IpHelper;
use common\helpers\ArrayHelper;
use common\logics\SmsCaptchaForm;
use common\logics\SpreadLogic;
use mpend\models\User;

/**
 * 帐号注册
 * @author emhome <emhome@163.com>
 * @since 2.0
 */
class RegisterForm extends Model {

    /**
     * @var string 手机号
     */
    public $mobile;

    /**
     * @var string 手机短信验证码
     */
    public $code;

    /**
     * @var string 密码
     */
    public $password;

    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            [['mobile', 'code', 'password'], 'required'],
            ['mobile', 'string', 'min' => 11, 'max' => 11],
            ['code', 'string', 'min' => 6, 'max' => 6],
            ['password', 'string', 'min' => 6, 'max' => 16],
            //['password', 'match', 'pattern' => static::passwordPattern(), 'message' => '密码过于简单需6~16位字符，建议字母数字符号组合'],
            ['mobile', '\common\validators\MobileValidator'],
            ['mobile', 'validateUser'],
            ['code', 'validateCaptcha'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels() {
        return [
            'mobile' => '手机号',
            'code' => '短信验证码',
            'password' => '密码',
        ];
    }

    /**
     * 校验密码是否正确
     * @param string $attribute the attribute currently being validated
     * @param array $params the additional name-value pairs given in the rule
     */
    protected static function passwordPattern() {
        return ArrayHelper::getValue(Yii::$app->params, 'format_pattern.password', '/(.*){6,16}/i');
    }

    /**
     * Validates the password.
     * This method serves as the inline validation for password.
     *
     * @param string $attribute the attribute currently being validated
     * @param array $params the additional name-value pairs given in the rule
     */
    public function validateUser($attribute) {
        if (!$this->hasErrors()) {
            $user = User::findByMobile($this->$attribute);
            if ($user) {
                $this->addError($attribute, '该手机号已注册，您可以使用手机号直接登录');
            }
        }
    }

    /**
     * Validates the password.
     * This method serves as the inline validation for password.
     *
     * @param string $attribute the attribute currently being validated
     * @param array $params the additional name-value pairs given in the rule
     */
    public function validateCaptcha($attribute) {
        if (!$this->hasErrors() && YII_ENV_PROD) {
            $captcha = Yii::$app->cache->get('captcha_' . SmsCaptchaForm::SCOPE_REGISTER . '_' . $this->mobile);
            if ($captcha == false) {
                $this->addError($attribute, $this->getAttributeLabel($attribute) . '已过期');
            } elseif ($captcha !== $this->$attribute) {
                $this->addError($attribute, $this->getAttributeLabel($attribute) . '不正确');
            }
        }
    }

    /**
     * 提交注册
     */
    public function register() {
        if (!$this->validate()) {
            $this->validateError('提交内容验证失败');
        }
        $user = $this->executeTransaction(__FUNCTION__);
        Yii::$app->cache->delete('captcha_' . SmsCaptchaForm::SCOPE_REGISTER . '_' . $this->mobile);

        if ($user) {
            try {
                SpreadLogic::joinBranch($this->mobile, $user->id);
            } catch (Exception $e) {
                Yii::error($e->getMessage());
            }
        }
        return $user;
    }

    /**
     * 注册数据保存
     * @inheritdoc
     */
    protected function transactRegister() {
        $user = new User();
        $user->setUsernameByMobile($this->mobile);
        $user->setPassword($this->password);
        $user->avatar = '/assets/avatar/default.png';
        $user->generateAuthKey();
        $user->ip = IpHelper::ip();
        if (!$user->save()) {
            throw new Exception('账号信息创建失败');
        }
        $meta = new UserMeta();
        $meta->id = $user->id;
        if (!$meta->save()) {
            throw new Exception('用户基本信息保存失败');
        }
        return $user;
    }

}
